/*
 *  extracts a feature-frequency map from the image
 *  feature is defined as an unique subimage defined by a set of relative
 *  coordinates to some white point constrained in a certain square
 *
 *   K - the limiting sqare's width
 *   N_min - minimum feature size
 *   N_max - maximum feature size
 *   N_supermax - features larger tha this are dropped (performance issues)
 *
 */

#include "image.hpp"

#include <vector>
#include <map>


#define K 5
#define N_min 5
#define N_max 7
#define N_supermax 8

using namespace std;

void add_multiple_features( vector<char> v, map<vector<char>,int> &out ){
  if( v.size() <= N_max*2 ){
    out[v] ++;
    return;
  }
//cout << v.size() << "\n";
  for( int x = 0; x < v.size()/2; x++ ){
    vector<char> o = v;
    o.erase(o.begin()+x*2);
    o.erase(o.begin()+x*2);
    add_multiple_features( o, out );
  }
}
void extract_features( img i, map<vector<char>,int> &out ){
  vector<char> v;
  for(char x = 0; x < i.Width(); x++){
    for(char y = 0; y < i.Height(); y++){
      if(i.p(x,y,0)){
        v.push_back(x);
        v.push_back(y);
      }
    }
  }
  if(v.size() < N_min*2) return;
  if(v.size() >= N_min*2 && v.size() <= N_max*2){
    vector<char> o;
    for( int l = 2; l < v.size(); l++ )
// substract the first point from all others
      o.push_back( v[l]-v[l%2] );
// iterate frecv
    out[o] ++;
  }
  else if(v.size() <= N_supermax*2){
// backtrack all the subfeatures if feature is too big
    add_multiple_features( v, out );
  }
}

int main( int argc, char ** argv ){
  if( argc == 1 ) return 0;

  img i(argv[1]);
  map<vector<char>, int> out;


  for( unsigned short x = 0; x < i.Width() - K; x ++ )
    for( unsigned short y = 0; y < i.Height() - K; y ++ ){
/*
 *  if there is no white pixel on the first row we can conclude that
 *  the feature will be caught by other steps
 */
      bool has_first_column_pixel = false;
      for( unsigned short _y = y; _y < y + K; _y ++ ){
        if( i.p(x,_y,0) ){
          has_first_column_pixel = true;
          break;
        }
      }
      if( has_first_column_pixel )
        extract_features(i.crop(x,y,x+K,y+K), out);
    }


/*
 *  the output will be in the following format:
 *   frecv x1 y1 x2 y2
 *   ....
 */

  for( auto it = out.begin(); it != out.end(); it++ ){
    cout << it->second << " ";
    for( auto it2 = it->first.begin(); it2 != it->first.end(); it2++ )
      cout << (int) *it2 << " ";
    cout << "\n";
  }

  return 0;
}
